import { chManager } from './defaultconfig.js';
import { DSP } from './dsphandler.js';
import { EQUtil } from './eq_util.js';

export class EqChartMask11 {
    constructor(myChartID, points, { delay = 30, onChange = null } = {}) {
        this.myChartID = myChartID;
        this.onChange = onChange || null;
        this.delay = delay;
        this.isSend = false;
        this.points = points;
        this.items = [];
        this.leftPoints = [];
        this.rightPoints = [];
        this.topContents = [];
        this.bottomContents = [];
        this.nums = [];
        this.createDOM();
    }

    createDOM() {
        this.my_chart = document.getElementById(this.myChartID);

        //遮罩
        this.mask = document.createElement('div');
        this.mask.id = "my_chart_mask";
        this.mask.style.margin = "0";
        this.mask.style.padding = "0";
        this.mask.style.width = "100%";
        this.mask.style.height = "100%";
        this.mask.style.border = "none";
        this.mask.style.background = "transparent";
        this.mask.style.boxSizing = "border-box";
        this.mask.style.position = "absolute";
        this.mask.style.top = "0px";
        this.mask.style.left = "0px";
        this.mask.style.zIndex = "2";
        this.my_chart.appendChild(this.mask);
    }

    ///全部更新
    refreshUI() {
        const item_width = this.my_chart.clientWidth / this.points.length * 2 - 30;
        if (this.items.length > 0) {
            this.points.forEach((x, index) => this.items[index].style.width = item_width + "px");
        } else {
            this.points.forEach((x, index) => {
                const item = this.initItem(x, item_width);
                const num = this.initNum(index);
                const top = this.initCellDiv(index, 1);
                const mid = this.initCellDiv(index, 2);
                const bottom = this.initCellDiv(index, 3);
                const leftPoint = this.initPoint(index, item_width, { isRight: false });
                const rightPoint = this.initPoint(index, item_width, { isRight: true });

                mid.appendChild(leftPoint);
                mid.appendChild(num);
                mid.appendChild(rightPoint);
                item.appendChild(top);
                item.appendChild(mid);
                item.appendChild(bottom);
                this.mask.appendChild(item);
                this.items.push(item);
                this.leftPoints.push(leftPoint);
                this.rightPoints.push(rightPoint);
                this.nums.push(num);
                this.topContents.push(top);
                this.bottomContents.push(bottom);
                this.addItemTouchEvents(item, index);
                this.addLeftOrRightPointTouchEvents(leftPoint);
                this.addLeftOrRightPointTouchEvents(rightPoint);
            });
        }
    }
    ///初始化整个频点滑动区域背景
    initItem(x, width) {
        const item = document.createElement("div");
        item.style.margin = "0";
        item.style.padding = "0";
        item.style.width = width + "px";
        item.style.height = "60px";
        item.style.border = "none";
        // item.style.background = "rgba(255, 255, 255, 0.1)";
        item.style.background = "transparent";
        item.style.boxSizing = "border-box";
        item.style.position = "absolute"
        item.style.top = this.my_chart.clientHeight / 2 - 20 + "px";
        item.style.left = x - this.mask.getBoundingClientRect().left / 2 + "px";
        item.style.display = "grid";          // 启用 Flex 布局
        item.style.gridTemplateRows = 'repeat(3,1fr)';
        item.style.alignItems = "center";
        return item;
    }

    ///初始化频点的数字
    initNum(index) {
        const label = document.createElement("div");
        label.textContent = `${index + 1}`;
        label.style.color = "white";
        label.style.textAlign = "center";
        label.style.background = "transparent";
        label.style.position = "relative";
        label.style.fontSize = '12px';
        label.style.width = '20px';
        label.style.cursor = "grabbing"; // 拖动中光标
        return label;
    }

    ///初始化背景区域上中下三个cell的背景
    initCellDiv(index, i) {
        const div = document.createElement('div');
        div.style.width = '100%';
        div.style.height = '100%';
        div.index = index;
        div.style.background = 'transparent';
        div.style.visibility = i === 2 ? 'visible' : 'hidden'; // 隐藏但保留空间
        div.style.display = i === 2 ? 'flex' : 'block';       // 非 flex 时用 block
        div.style.justifyContent = i === 2 ? "center" : 'center';
        div.style.alignItems = "center";
        div.style.fontSize = '10px';
        div.style.textAlign = 'center';
        div.style.position = 'relative';  // 添加相对定位
        div.id = `ball_cell_${index}` + ['top', 'mid', 'bottom'][i - 1];
        div.className = i === 2 ? 'ball_cell_mid' : 'ball_cell';
        return div;
    }

    ///初始化捏合变化Q值的小圆点
    initPoint(index, width, { isRight = true }) {
        const pointcheck = document.createElement('div');
        pointcheck.id = isRight ? `right_check${index}` : `left_check${index}`;
        pointcheck.isLeft = !isRight;
        pointcheck.index = index;
        pointcheck.style.width = '10px';
        pointcheck.style.aspectRatio = 1;
        pointcheck.style.background = 'transparent';
        pointcheck.style.border = '1px solid #ccc';
        pointcheck.style.borderRadius = '50%';
        pointcheck.style.cursor = 'pointer';
        pointcheck.style.transition = 'background-color 0.3s';
        pointcheck.style.visibility = 'hidden'; // 隐藏但保留空间
        pointcheck.style.position = 'absolute';
        pointcheck.className = "point_check_div";
        pointcheck.style.left = isRight ? `${width / 4 * 3 + 5}px` : `${width / 4 - 5}px`;
        return pointcheck;
    }

    ///添加 频点的手势响应
    addItemTouchEvents(element, index) {
        let isDragging = false;
        let offsetX, offsetY;
        const num = this.nums[index];
        const handleMouseMove = (e) => {
            if (!isDragging) return;
            // this.updatePosition(ball, e.clientX - offsetX, e.clientY - offsetY);
            this.mouseMoveToFreq(index, e.clientX - offsetX, e.clientY - offsetY);
        };

        const handleMouseUp = () => {
            if (isDragging) {
                isDragging = false;
                element.style.zIndex = "1";
                document.removeEventListener("mousemove", handleMouseMove);
                document.removeEventListener("mouseup", handleMouseUp);
            }
        };

        num.onmousedown = (e) => {
            isDragging = true;
            this.items.forEach(b => b.style.zIndex = "1");
            element.style.zIndex = '100';

            // 计算鼠标在ball的偏移量
            const rect = element.getBoundingClientRect();
            offsetX = e.clientX - rect.left;
            offsetY = e.clientY - rect.top;
            this.updateItemtatus(index);

            // 绑定到 document
            document.addEventListener("mousemove", handleMouseMove);
            document.addEventListener("mouseup", handleMouseUp);

            e.preventDefault();
        };
    }
    ///
    updateItemtatus(index) {
        for (let i = 0; i < this.topContents.length; i++) {
            const top = this.topContents[i];
            const bottom = this.bottomContents[i];
            const leftPoint = this.leftPoints[i];
            const rightPoint = this.rightPoints[i];
            top.style.visibility = top.index === index ? 'visible' : 'hidden';
            bottom.style.visibility = 'hidden';
            leftPoint.style.visibility = leftPoint.index === index ? 'visible' : 'hidden';
            rightPoint.style.visibility = rightPoint.index === index ? 'visible' : 'hidden';
        }
    }

    ///添加左  ｜ 右，小圆点手势 响应
    addLeftOrRightPointTouchEvents(point) {
        let isDragging = false;
        let startX = 0;
        let otherPoint;

        const handleMouseMove = (e) => {
            e.stopPropagation();
            e.preventDefault();
            if (!isDragging) return;

            const item = this.items[point.index]; // 获取 ball 元素
            const num = this.nums[point.index];

            // 检查鼠标是否在 ball 范围内
            const itemRect = item.getBoundingClientRect();
            if (
                e.clientX < itemRect.left ||
                e.clientX > itemRect.right ||
                e.clientY < itemRect.top ||
                e.clientY > itemRect.bottom
            ) {
                // 如果超出范围，立即停止拖拽
                handleMouseUp();
                return;
            }

            // 获取父元素位置（关键修正点）
            const parentRect = point.parentElement.getBoundingClientRect();
            const mouseX = e.clientX - parentRect.left; // 转换为相对坐标
            const deltaX = mouseX - startX;
            startX = mouseX;

            const item_w = item.clientWidth;
            const currentLeft = parseInt(point.style.left);
            let newLeft = currentLeft + deltaX;

            // 动态计算边界
            const pointWidth = point.clientWidth;
            const lableWidth = num.clientWidth;
            const minLeft = point.isLeft ? 0 : item_w / 2 + lableWidth / 2;
            const maxLeft = point.isLeft ? item_w / 2 - pointWidth - lableWidth / 2 : item_w - pointWidth;

            newLeft = Math.max(minLeft, Math.min(maxLeft, newLeft));
            const otherNewLeft = item_w - newLeft - pointWidth;

            // 更新当前点,   // 对称更新另一
            point.style.left = `${newLeft}px`;
            otherPoint.style.left = `${otherNewLeft}px`;

            // Q值计算逻辑（保持不变）
            const sign = chManager.current_chlist[0].sign_list[point.index];
            const scale_q = sign.max_q / (item_w / 2 - pointWidth - lableWidth / 2);
            let q = parseFloat(point.isLeft ? newLeft : otherNewLeft) * scale_q;
            q = Math.max(sign.min_q, Math.min(q, sign.max_q));
            q = Math.round(q * 10) / 10;
            this.updateSign(sign.gain, sign.freq, q, point.index);
        };

        const handleMouseUp = (e) => {
            isDragging = false;
            point.style.transition = 'background-color 0.3s';
            point.style.background = 'transparent';
            otherPoint.style.background = 'transparent';
            point.style.zIndex = "";
            otherPoint.style.zIndex = "";
            document.removeEventListener("mousemove", handleMouseMove);
            document.removeEventListener("mouseup", handleMouseUp);
        }

        point.onmousedown = (e) => {
            e.stopPropagation();
            e.preventDefault();
            window.getSelection().removeAllRanges(); // 清除已有文本选中

            const parentRect = point.parentElement.getBoundingClientRect(); // 关键修正点
            startX = e.clientX - parentRect.left; // 起始位置转为相对坐标

            otherPoint = point.isLeft ? this.rightPoints[point.index] : this.leftPoints[point.index];
            isDragging = true;

            point.style.transition = 'none'; // 拖动时禁用过渡
            point.style.background = '#ccc';
            otherPoint.style.background = '#ccc';
            point.style.zIndex = "100";
            otherPoint.style.zIndex = "100";

            // 绑定到 document
            document.addEventListener("mousemove", handleMouseMove);
            document.addEventListener("mouseup", handleMouseUp);
        }
    }

    /**
    * 更新ball的位置，x
    * @param {number} index - ball
    * @param {number} ball_left - ball的左顶点
    * @param {number} ball_top - ball的上顶点
    */
    updatePosition(index, ball_left, ball_top) {

        const item = this.items[index];
        const w = item.clientWidth;
        const num = this.nums[index];

        item.style.width = w + "px";
        // 获取父容器边界信息（只计算一次）
        const parentRect = this.mask.getBoundingClientRect();
        const parentWidth = this.mask.clientWidth;
        const parentHeight = this.mask.clientHeight;

        // // 计算中心点偏移（假设需要以中心点为基准）
        const centerOffsetX = item.clientWidth / 2;
        const centerOffsetY = item.clientHeight / 2;

        // 计算相对位置（减去父容器偏移和初始点击偏移）
        const newX = ball_left - parentRect.left - centerOffsetX;
        const newY = ball_top - parentRect.top - centerOffsetY;

        // 边界检查（动态计算最大范围）
        const maxX = parentWidth - centerOffsetX;
        const maxY = parentHeight - centerOffsetY;

        // 应用边界限制
        const clampedX = Math.max(-centerOffsetX, Math.min(newX, maxX));
        const clampedY = Math.max(-centerOffsetY, Math.min(newY, maxY));

        // 更新位置
        item.style.left = `${clampedX}px`;
        item.style.top = `${clampedY}px`;
        item.style.zIndex = "100"

        ///更新左右圆点的位置
        const leftPoint = this.leftPoints[index];
        const rightPoint = this.rightPoints[index];
        const pointWidth = leftPoint.clientWidth;
        const numWidth = num.clientWidth;

        const sign = chManager.current_chlist[0].sign_list[index];
        const scale_q = (w / 2 - pointWidth - numWidth / 2) / sign.max_q;
        leftPoint.style.left = `${scale_q * sign.q}px`;
        rightPoint.style.left = `${w - pointWidth - scale_q * sign.q}px`;

        this.updateSign(sign.gain, sign.freq, sign.q, index, { onlyRefreshUI: true });
    }

    mouseMoveToFreq(index, ball_left, ball_top) {
        const item = this.items[index];
        const w = item.clientWidth / 2;
        const h = item.clientHeight / 2;

        ///算出ball的中心点到左顶点的距离
        let centerX = ball_left + w;
        let centerY = ball_top + h;

        ///计算ball的中心点距离父元素的左顶点的距离
        const parentRect = this.mask.getBoundingClientRect();
        const parentWidth = this.mask.clientWidth;
        const parentHeight = this.mask.clientHeight;

        centerX = centerX - parentRect.left;
        centerY = centerY - parentRect.top;

        ///根据移动的gain上下位置，决定ball_content是显示上面的还是下面的
        const over_top = centerY - parentRect.top <= 0;
        const over_bottom = parentRect.top + parentHeight - centerY <= 0;
        for (let i = 0; i < this.topContents.length; i++) {
            const top = this.topContents[i];
            const bottom = this.bottomContents[i];
            top.style.visibility = over_top || top.index !== index ? 'hidden' : 'visible';
            bottom.style.visibility = over_bottom || top.index !== index || !over_top ? 'hidden' : 'visible';
        }


        //1.  把中心点x，转换成Freq
        const freq = Math.round(EQUtil.deInt(centerX, this.my_chart.clientWidth, 0));

        //2. 把中心点y，转换成Gain
        const sign = chManager.current_chlist[0].sign_list[index];
        const scale = (sign.max_gain - sign.min_gain) / this.mask.clientHeight;
        let gain = centerY * scale;
        gain = Math.max(0, Math.min(gain, (sign.max_gain - sign.min_gain)));
        gain = Math.round((parseInt(sign.max_gain) - gain) * 10) / 10;

        this.updateSign(gain, freq, sign.q, index);
    }

    updateSign(gain, freq, q, index, { onlyRefreshUI = false } = {}) {
        for (let i = 0; i < this.topContents.length; i++) {
            const top = this.topContents[i];
            const bottom = this.bottomContents[i];
            if (top.index !== index) continue;
            top.textContent = 'G:' + `${gain}` + ' F:' + `${freq}` + ' Q:' + `${q}`;
            bottom.textContent = 'G:' + `${gain}` + ' F:' + `${freq}` + ' Q:' + `${q}`;
        }
        if (onlyRefreshUI) return;

        chManager.current_chlist.forEach(ch => {
            ch.sign_list[index].freq = Math.round(freq);
            ch.sign_list[index].gain = gain;
            ch.sign_list[index].q = q;
        });

        if (this.onChange) {
            this.onChange();
        }
        ///
        if (this.isSend === false) {
            DSP.updateEQ(gain, freq, q, index);
            this.isSend = true;
            setTimeout(() => this.isSend = false, this.delay);
        }
    }
}